home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / source / synt.asm < prev    next >
Encoding:
Assembly Source File  |  1992-09-30  |  7.4 KB  |  298 lines

  1.     page    132,63,1,1
  2.     opt    rc
  3.     title    'LPC Synthesis'
  4.  
  5. ;***************************************************************
  6. ;* SYNT.ASM -- 2400 bit/s LPC synthesizer module           *
  7. ;*                                   *
  8. ;* Provides excitation source and Lattice filter for speech    *
  9. ;* generation.                               *
  10. ;*                                   *
  11. ;* The overall implementation is based on application note     *
  12. ;*    Seshan, N.:                           *
  13. ;*    "A TMS320C30-based LPC Vocoder",               *
  14. ;*    Texas Instruments, 1990                    *
  15. ;*                                   *
  16. ;* Lattice filter implementation is based on Motorola sample   *
  17. ;* code and book                           *
  18. ;*    Proakis, J., G.:                       *
  19. ;*    "Digital Communications",                   *
  20. ;*    McGraw-Hill, 1983                       *
  21. ;*                                   *
  22. ;* Copyright (C) 1992 by Alef Null. All rights reserved.       *
  23. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  24. ;* Modification(s):                           *
  25. ;*    30-Sep-92: added monotonic mode                *
  26. ;***************************************************************
  27.  
  28.     section LPCsyn
  29.     xdef    lpc_syn
  30.  
  31.     org    p:
  32.  
  33.     nolist
  34.     include 'macros'
  35.     list
  36.  
  37.  
  38. ; Synthesize output from LPC parameters
  39. lpc_syn move            #-1,m0
  40.     move            m0,m4
  41.  
  42.     jclr    #monot,x:<flags,_inton            ; set to constant pitch if monotonic mode
  43.     move            x:<p_s,a            ; and current frame is voiced
  44.     tst    a        #>monopit,x0
  45.     tne    x0,a
  46.     move            a1,x:<p_s
  47.  
  48. _inton    jclr    #whisper,x:<flags,_voice        ; remove voicing if in whisper mode
  49.     clr    a
  50.     move            a,x:<p_s
  51.  
  52. _voice    move            x:<p_s,a            ; test if voiced
  53.     tst    a        x:<p_d,x0
  54.     jeq    <_novc
  55.     add    x0,a        #>10,x0            ; then adjust pitch
  56.     cmp    x0,a                    ; set floor on adjustment
  57.     tlt    x0,a
  58.     move            a,x:<p_s
  59.     jmp    <_vcend
  60.  
  61. _novc    move            #>boost,x0            ; if unvoiced boost gain
  62.     move            x:<g_s,x1
  63.     mpy    x0,x1,a
  64.     lsl    a                    ; adjust fraction (fraction, integer multiplication)
  65.     asr    a
  66.     move            a0,x:<g_s
  67.  
  68. _vcend    jclr    #silence,x:<flags,_loud         ; set gain to zero if in silence mode
  69.     clr    a
  70.     move    a,x:<g_s
  71. _loud
  72.  
  73. ; Interpolate if voicing of previous frame and current frame is same
  74.     move            #-1,x0            ; first convert pitchs to logical values
  75.     move            x:<p_s,a
  76.     tst    a        x:<p_s_0,b
  77.     tne    x0,a
  78.     tst    b        a,x1
  79.     tne    x0,b
  80.  
  81.     bclr    #ipolate,x:<flags            ; then set interpolate flag if they are different
  82.     eor    x1,b
  83.     jne    <_clripo
  84.     bset    #ipolate,x:<flags
  85. _clripo
  86.  
  87. ; If interpolating initialize with last frames parameters
  88.     jclr    #ipolate,x:<flags,noipo
  89.  
  90.     move            #<k_s_0,r0            ; copy k_s_0[] to k_int[]
  91.     move            #<k_int,r4
  92.     do    #P,_endip
  93.     move            x:(r0)+,a1
  94.     move            a1,x:(r4)+
  95. _endip
  96.  
  97.     move            x:<g_s_0,a1         ; g_s_0 -> g_int
  98.     move            a1,x:<g_int
  99.  
  100.     jmp    <ipo
  101.  
  102. ; else reset interpolation index (exite), initialize system with
  103. ; current frame's LPC parameters and clear backward lattice state
  104. noipo    clr    a        x:<g_s,b1            ; 0   -> excite
  105.     move            a,x:<excite         ; g_s -> g_int
  106.     move            b1,x:<g_int
  107.  
  108.     move            #<b_s,r0            ; clear b_s[]
  109.     move            r0,x:<b_s_ptr
  110.     rep    #P
  111.     move            a,y:(r0)+
  112.  
  113.     move            #<k_s,r0            ; copy k_s[] to k_int[]
  114.     move            #<k_int,r4
  115.     do    #P,_refcpy
  116.     move            x:(r0)+,a1
  117.     move            a1,x:(r4)+
  118. _refcpy
  119.  
  120. ; if unvoiced set interpolation interval to 1/8 frame size
  121. ipo    move            x:<p_s,a
  122.     tst    a        #>M/8,x0
  123.     jeq    <ipintv
  124.  
  125. ; else set interpolation interval to pitch. If interpolation
  126. ; is on set to last frame's pitch, otherwise set to current frame's pitch
  127. von    move            x:<p_s_0,x0         ; p_int = interpolate ? p_s_0 : p_s
  128.     jset    #ipolate,x:<flags,ipintv
  129.     move            x:<p_s,x0
  130. ipintv    move            x0,x:<p_int
  131.  
  132. ;
  133.     move            x:samptr,r0
  134.     move            #3*M-1,m0
  135.     do    #M,frmend
  136.     move            r0,b            ; sample index to b
  137.     move            x:samptr,x0
  138.     sub    x0,b        x:<excite,a         ; check if end of interpolation interval
  139.     cmp    a,b
  140.     jne    <genexc
  141.  
  142. ; If interpolation flag, interpolate between previous and current frame
  143.     jclr    #ipolate,x:<flags,nxtipo
  144.  
  145.     move            b,x0            ; x0 = index/M, y0 = (M - index)/M
  146.     move            #1.0/@cvf(M),x1
  147.     mpy    x0,x1,a     #0.9999999,b
  148.     lsl    a                    ; adjust fraction part
  149.     asr    a
  150.     move            a0,x0
  151.     sub    x0,b        x:<p_s,a
  152.  
  153.     tst    a        b,y0            ; p_int = (i*p_s + l*p_s_0)/M
  154.     jeq    <_nopitch
  155.     move    a,x1
  156.     mpy    x0,x1,a     x:<p_s_0,y1
  157.     macr    y0,y1,a
  158.     move            a,x:<p_int
  159. _nopitch
  160.  
  161.     move            #<k_s,r1            ; k_int[j] = (i*k_s[j] + j*k_s_0[j])/M
  162.     move            #<k_s_0,r4
  163.     move            #<k_int,r5
  164.     move            #-1,m1
  165.     move            m1,m5
  166.     do    #P,_refipo
  167.     move            x:(r1)+,x1
  168.     mpy    x0,x1,a     x:(r4)+,y1
  169.     macr    y0,y1,a
  170.     move            a,x:(r5)+
  171. _refipo
  172.  
  173.     move            x:<g_s,x1            ; g_int = (i*g_s + l*g_s_0)/M
  174.     mpy    x0,x1,a     x:<g_s_0,y1
  175.     macr    y0,y1,a
  176.     move            a,x:<g_int
  177.  
  178. nxtipo    move            x:<excite,a         ; set next interpolation point
  179.     move            x:<p_int,x0
  180.     add    x0,a        #glottal,b1         ; reset glottal pulse pointer
  181.     move            a1,x:<excite
  182.     move            b1,x:<pulse
  183.  
  184. ; Generate excitation
  185. genexc    move            x:<p_s,b
  186.     tst    b        x:<rand,a1
  187.     jeq    <noise
  188.  
  189. ; voiced, use 40 point DoD glottal pulse excitation
  190.     move            x:<pulse,b            ; give zero if end of excitation sequence
  191.     clr    a        #>glottal+40,x0
  192.     cmp    x0,b        x:<pulse,r4
  193.     jge    <genout
  194.     move            x:<p_int,x0         ; pulse[]*p_int/p_max*g_int
  195.     move            #1.0/(197.0+1.0),x1
  196.     mpy    x0,x1,a     y:(r4)+,x0
  197.     move    a0,x1
  198.     mpyr    x0,x1,a     x:<g_int,x0
  199.     move    a,x1
  200.     mpyr    x0,x1,a     r4,x:<pulse
  201.     jmp    <genout
  202.  
  203. ; otherwise generate white noise excitation with random bit
  204. noise    lsr    a        #>poly,x0             ; generate a new radom bit to C flag
  205.     jcc    <_rand
  206.     eor    x0,a
  207. _rand    move            a,x:<rand
  208.  
  209.     move            x:<g_int,a            ; compose excitation value
  210.     jcs    <_scale
  211.     neg    a
  212. _scale    move    a,x0                    ; scale output
  213.     move            #1.0/25.0,x1
  214.     mpyr    x0,x1,a
  215.  
  216. ; exite lattice filter and deemphasize output (excitation in a register)
  217. genout    move            #<k_int+P-1,r1
  218.     move            x:<b_s_ptr,r5
  219.     move            #P-1,m5
  220.     nop
  221.  
  222.     move            x:(r1)-,x0    y:(r5)+,y0  ; Lattice macro from Motorola bulletin board
  223.     macr    -x0,y0,a    x:(r1)-,x0    y:(r5)-,y0
  224.     do    #P-1,_endlat
  225.     macr    -x0,y0,a        b,y:(r5)+
  226.     move    a,x1            y:(r5)+,b
  227.     macr    x1,x0,b     x:(r1)-,x0    y:(r5)-,y0
  228. _endlat
  229.     move                b,y:(r5)+
  230.     move            x:(r1)+,x0    a,y:(r5)+
  231.     move            r5,x:<b_s_ptr
  232.  
  233.     move            x:<old,x0            ; deemphasize
  234.     move            #0.9375,x1
  235.     macr    x0,x1,a     #>$fffc<<8,x0
  236.     move            a,x:<old
  237.  
  238.     rep    #5                    ; scale output
  239.     asl    a
  240.  
  241.     and    x0,a                    ; finally output
  242.     move            a1,y:(r0)+
  243. frmend
  244.  
  245.     move            x:<excite,a         ; reset next excitation point for next frame
  246.     move            #>M,x0
  247.     sub    x0,a        x:<g_s,x0            ; save current values for next frame
  248.     move            a,x:<excite
  249.  
  250.     move            x0,x:<g_s_0
  251.  
  252.     move            x:<p_s,x0
  253.     move            x0,x:<p_s_0
  254.  
  255.     move            #<k_s,r0
  256.     move            #-1,m0
  257.     move            #<k_s_0,r4
  258.     do    #P,_ef
  259.     move            x:(r0)+,a1
  260.     move            a1,x:(r4)+
  261. _ef
  262.  
  263.     rts
  264.  
  265.  
  266. ;****************************
  267. ;*     DATA - AREA        *
  268. ;****************************
  269.  
  270.     org    x:
  271.  
  272. k_s_0    ds    P                    ; previous reflection coefficients
  273.  
  274. g_s_0    ds    1                    ; gain for previous output frame
  275. old    dc    0                    ; previous output value
  276.  
  277. p_s_0    ds    1                    ; previous output pitch period
  278. pulse    ds    1                    ; index to glottal excitation
  279. excite    dc    0                    ; sample for next parameter interpolation
  280.  
  281. g_int    ds    1                    ; interpolated gain
  282. p_int    ds    1                    ; interpolated pitch
  283. k_int    ds    P                    ; interpolated reflection coefficients
  284.  
  285. rand    dc    $12345                    ; random number generator seed
  286.  
  287. b_s_ptr ds    1
  288.  
  289.  
  290.     org    y:
  291.  
  292.     ds    14
  293. b_s    ds    P                    ; backward lattice state
  294.  
  295.     endsec
  296.  
  297.     end
  298.